package com.z.system.controller;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.z.system.model.User;
import com.z.system.repository.RoleRepository;
import com.z.system.repository.UserRepository;
import com.z.system.utils.JwtTokenUtil;
import com.z.system.utils.R;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 认证控制器，处理用户登录和注册请求
 */
@RestController
@RequestMapping("/api/auth")
@Tag(name = "认证管理", description = "用户认证相关接口")
public class AuthController {

    private final AuthenticationManager authenticationManager;
    private final JwtTokenUtil jwtTokenUtil;

    public AuthController(
            AuthenticationManager authenticationManager,
            UserRepository userRepository,
            PasswordEncoder passwordEncoder,
            JwtTokenUtil jwtTokenUtil,
            RoleRepository roleRepository) {
        this.authenticationManager = authenticationManager;
        this.jwtTokenUtil = jwtTokenUtil;
    }

    /**
     * 用户登录接口
     */
    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户登录认证接口，返回token和refreshToken", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = LoginRequest.class))))
    public ResponseEntity<?> login(
            @Parameter(description = "登录请求参数", required = true) @RequestBody LoginRequest loginRequest) {
        try {
            // 认证用户
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(loginRequest.getUserName(), loginRequest.getPassword()));
            // 设置认证上下文
            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 生成JWT令牌和刷新令牌
            User user = (User) authentication.getPrincipal();
            String token = jwtTokenUtil.generateToken(user.getUserSn());
            String refreshToken = jwtTokenUtil.generateRefreshToken(user.getUserSn());

            // 创建响应数据对象，包含token和refreshToken
            Map<String, String> data = new HashMap<>();
            data.put("token", token);
            data.put("refreshToken", refreshToken);

            // 返回统一格式的响应，消息为"登录成功"
            return ResponseEntity.ok(R.success("登录成功", data));
        } catch (Exception e) {
            // 记录日志
            Logger logger = LoggerFactory.getLogger(AuthController.class);
            logger.debug("Login failed for user: {}", loginRequest.getUserName(), e);
            return ResponseEntity.ok(R.error(e.getMessage()));
        }

    }

    // 请求和响应对象
    public static class LoginRequest {
        private String userName;
        private String password;

        // Getters and Setters
        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    public static class RegisterRequest {
        private String username;
        private String email;
        private String password;

        // Getters and Setters
        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    public static class JwtResponse {
        private String token;
        private String type = "Bearer";
        private String username;
        private Object roles;

        public JwtResponse(String accessToken, String username, Object roles) {
            this.token = accessToken;
            this.username = username;
            this.roles = roles;
        }

        // Getters
        public String getToken() {
            return token;
        }

        public String getType() {
            return type;
        }

        public String getUsername() {
            return username;
        }

        public Object getRoles() {
            return roles;
        }
    }

    public static class MessageResponse {
        private String message;

        public MessageResponse(String message) {
            this.message = message;
        }

        // Getter
        public String getMessage() {
            return message;
        }
    }
}